package com.ywu.standard.gateway.filter;

import com.ywu.boot.context.YwuContext;
import com.ywu.boot.context.YwuContextHolder;
import com.ywu.common.utils.TimerIdGenerateUtil;
import com.ywu.standard.gateway.entity.GatewayApiEntity;
import com.ywu.standard.gateway.handler.HandlerInterface;
import com.ywu.standard.gateway.handler.header.impl.HeaderHandlerInterface;
import com.ywu.standard.gateway.service.GatewayApiRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * @ClassName HeaderHandlerFilter
 * @Description 请求头处理
 * @Author GroundDemo
 * @Date 2024/5/26 9:57
 * @Version 1.0
 **/
@Component
@Slf4j
public class HeaderHandlerFilter implements GlobalFilter, Ordered, HandlerInterface {
    @Autowired
    private List<HeaderHandlerInterface> headerHandlerList;

    @Autowired
    private GatewayApiRecordService service;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 打印接口信息
        String path = exchange.getRequest().getPath().toString();
        log.info("request path is {}", path);
        log.info("HeaderHandlerFilter start! headerHandlerList size is {}", headerHandlerList.size());
        // 初始化上下文对象
        YwuContext ywuContext = new YwuContext();
        YwuContextHolder.setCurrentContext(ywuContext);
        Date beforeRequestDate = new Date();
        for (HeaderHandlerInterface impl : headerHandlerList) {
            Object handleRes = impl.handle(exchange);
            // 校验返回值是否为ServerWebExchange对象，如果不是，则构造返回体进行返回
            if (handleRes instanceof ServerWebExchange) {
                exchange = (ServerWebExchange) handleRes;
            } else {
                return generateResponseInfo(exchange, handleRes);
            }
        }
        log.info("HeaderHandlerFilter end!");
        Mono<Void> filter = chain.filter(exchange);
        ServerWebExchange finalExchange = exchange;
        return filter.doFinally(res -> {
            addApiRecord(finalExchange, beforeRequestDate, ywuContext);
        });
    }

    /**
    * @Author GroundDemo
    * @Description 将当前接口的请求状态记录至数据库中（优先记录本地缓存，满了之后刷新至数据库）
    * @Date 10:29 2025/3/24
    * @Param [finalExchange, beforeRequestDate, ywuContext]
    * @return void
    **/
    private void addApiRecord(ServerWebExchange finalExchange, Date beforeRequestDate, YwuContext ywuContext) {
        Date afterRequestDate = new Date();
        // 构建对象
        GatewayApiEntity entity = new GatewayApiEntity();
        entity.setId(TimerIdGenerateUtil.nextId());
        entity.setUrl(finalExchange.getRequest().getPath().toString().split("\\?")[0]);
        HttpMethod method = finalExchange.getRequest().getMethod();
        entity.setMethod(method == null ? "NONE" : method.name());
        HttpStatus statusCode = finalExchange.getResponse().getStatusCode();
        entity.setStatusCode(statusCode == null ? "500" : String.valueOf(statusCode.value()));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String format = simpleDateFormat.format(beforeRequestDate);
        entity.setAccessTime(format);
        long time = afterRequestDate.getTime() - beforeRequestDate.getTime();
        entity.setTime(time);
        // 调用方法进行记录
        service.addApiRecord(entity, ywuContext);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
